<?php

class Catalogue_Form_Object extends Workset_Form {

	const CATEGORY_PREFIX = 'c';
    const PARAM_CATEGORY = 'nodeid';

	const SAVE_MODE = "save_mode";
	const CLONE_MODE = "clone_mode";
	const APPLY_MODE = "apply_mode";

	const ATTR_PREFIX = 'attr';
    const ATTR_VALUE_SPR = '_';

    const DISPLAY_GROUP_PREFIX = 'd';
	
    const UPLOAD_FILE_SIZE = 10;
	const UPLOAD_FILE_COUNT= 20;

	protected static $_editModes = array(
		self::SAVE_MODE	=> array(
			'order' => 10001,
			'title' => 'Сохранить',
			'value' => 1
		),
        self::APPLY_MODE => array(
			'order' => 10000,
			'title' => 'Применить',
			'value' => 1
		),
        self::CLONE_MODE => array(
			'order' => 10002,
			'title' => 'Копировать текущий объект',
			'value' => 1
		),
	);

	protected static $_attrDefaultDecoratorOrder = array(
		'default' => array(
			'ViewHelper' 	=> 0,
			'Errors' 		=> 1,
			'Button' 		=> 2,
			'Description'	=> 3,
			'HtmlTag'		=> 4,
			'Label'			=> 5
		),

		Workset_Model_Value_Type_Interface::T_FILE => array(
			'File' 			=> 0,
			'Errors' 		=> 1,
			'Attachment' 	=> 2,
			'Button' 		=> 3,
			'Description'	=> 4,
			'HtmlTag'		=> 5,
			'Label'			=> 6
		)
	);

    protected static $_attrDefaultDecorators = array(
        Workset_Model_Value_Type_Interface::T_FILE => array(
            array('decorator' => 'File'),
            array('decorator' => 'Errors'),
            'Attachment',
            'Button',
            array('decorator' => 'Description', 'options' => array(
                'tag' => 'div',
                'class' => 'description',
                'escape' => false
            )),
            array('decorator' => 'HtmlTag', 'options' => array(
                'tag' => 'dd',
            )),
            array('decorator' => 'Label', 'options' => array(
                'tag' => 'dt'
            ))
        ),

        'default' => array(
            array('decorator' => 'ViewHelper'),
            array('decorator' => 'Errors'),
            'Button',
            array('decorator' => 'Description', 'options' => array(
                'tag' => 'div',
                'class' => 'description',
                'escape' => false
            )),
            array('decorator' => 'HtmlTag', 'options' => array(
                'tag' => 'dd',
            )),
            array('decorator' => 'Label', 'options' => array(
                'tag' => 'dt'
            ))
        ),

		'hidden' => array(
			array('decorator' => 'ViewHelper'),
		)
    );

	protected $_initAttrFields = false;

    protected $_initForm = false;

    protected $_editMode = null;

    protected $_attrElements = array();

    protected $_attrElementOrder = 0;

	protected $_attrDisplayGroupOrder = 1000;

    protected $_attrGroups = array();

    protected $_attrToGroup = array();

    protected $_attrDecorators = array();

	protected $_attrDecoratorOrder = array();

	protected $_displayGroupDecorators = array(
		array('decorator' => 'FormElements'),
		array(
			'decorator' => 'HtmlTag',
			'options' => array(
				'tag' => 'dl'
			)
		),
		array('decorator' => 'Fieldset'),
	);

    protected $_attrOptions = array();

	protected $_namedPrefixs = array(self::ATTR_PREFIX);

    /**
     * Сохраняет ID выбранных категорий в полях формы
     *
     * @param  $categoryIds
     * @param  $name
     * @return Catalogue_Form_Object
     */
    function setCategory($categoryIds, $name = null) {
        $name = null !== $name ? $this->filterName($name, true) : self::PARAM_CATEGORY;
        if ($name && null === $this->getElement('category_id')) {
            if (is_array($categoryIds)) {
                $q = array();
                foreach ($categoryIds as $key => $id) {
                    $q[self::CATEGORY_PREFIX.$key] = $id;
                }
                $belognsTo = $name;
                $categoryIds = $q;
                $q = array($name => array_values($q));
            } else {
                $belognsTo = null;
                $q = $categoryIds = array($name => (int)$categoryIds);
            }

            $this->addActionParams($q);

            foreach ($categoryIds as $name => $id) {
                $this->addElement('hidden', $name, array(
                    'required' => true,
                    'decorators' => array('ViewHelper', 'Errors'),
                    'filters' => array('Int'),
                    'value' => $id,
                    'belongsTo' => $belognsTo
                ));
            }
        }
        return $this;
    }

	function addEditMode($mode, $label = null) {
		if (isset(self::$_editModes[$mode])) {
			$options = self::$_editModes[$mode];

			if (null !== $label) {
				$options['label'] = (string)$label;
			}
			$this->addElement('submit', $mode, $options);
		}
		return $this;
	}

	function addEditModes(array $modes) {
		foreach ($modes as $mode) {
			if (is_array($mode)) {
				$label = isset($mode['label']) ? $mode['label'] : null;
				$mode = isset($mode['mode']) ? $mode['mode'] : current($mode);
			} else {
				$label = null;
			}
			$this->addEditMode($mode, $label);
		}
		return $this;
	}

    function getEditMode() {
        return $this->_editMode;
    }

    function addAttrField(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null, $belongsTo = null) {

        if (!is_array($options)) {
            $options = array();
        }

        if (null === $value) {
            $value = $attr->getValue();
        }

        if (null !== $belongsTo) {
            $belongsTo = (string)$belongsTo;
        } elseif (isset($options['belongsTo'])) {
            $belongsTo = $options['belongsTo'];
        } else {
            $belongsTo = self::ATTR_PREFIX;
        }

        if ($attr->isMultiple() && !$attr->isEnum() && !$attr->isSelect()) {
			$belongsTo = $attr->getHtmlId($belongsTo);

			if (isset($options['attribs'])) {
				$options['attribs']['rel'] = $attr->getModelId();
			} else {
				$options['attribs'] = array(
					'rel' => $attr->getModelId()
				);
			}
        }

        $options['belongsTo'] = $belongsTo;
        $options['required'] = $attr->isRequired(Workset_Model_Value_Form_Interface::REQUIRED);

        if (!isset($options['label'])) {
            $options['label'] = $attr->getName();
        }

        if ($attr->isEnum()) {
            $this->addAttrFieldSelect($attr, $value, $options);
        } else {

            switch ($attr->getType()) {

                case Workset_Model_Value_Form_Interface::T_INT:
                case Workset_Model_Value_Form_Interface::T_DECIMAL:
                case Workset_Model_Value_Form_Interface::T_STRING:

                    $this->addAttrFieldText($attr, $value, $options);

                    break;

                case Workset_Model_Value_Form_Interface::T_BOOL:

                    $this->addAttrFieldCheckbox($attr, $value, $options);

                    break;

                case Workset_Model_Value_Form_Interface::T_TEXT:

                    $this->addAttrFieldTextarea($attr, $value, $options);

                    break;

                case Workset_Model_Value_Form_Interface::T_FILE:
                case Workset_Model_Value_Form_Interface::T_IMAGE:
                case Workset_Model_Value_Form_Interface::T_VIDEO:

                    $this->addAttrFieldFile($attr, $value, $options);

                    break;

                case Workset_Model_Value_Form_Interface::T_SELECT:

                    $this->addAttrFieldSelect($attr, $value, $options);

                    break;

                default:
                    $this->addAttrFieldText($attr, $value, $options);

            }
        }
    }

    function addAttrFieldGroup($group, $order = null, $options = null) {
        $group = self::DISPLAY_GROUP_PREFIX.'_'.$group;

        if (null === $order) {
            $order = count($this->_attrGroups);
        }

        if (!is_array($options)) {
            $options = array('order' => $order);
        } else {
            $options['order'] = $order;
        }

        $this->_attrGroups[$group] = $options;
    }

    function addAttrToGroup($group, Workset_Model_Value_Form_Interface $attr) {
        $group = self::DISPLAY_GROUP_PREFIX.'_'.$group;

        if (!isset($this->_attrGroups[$group])) {
            return;
        }

        $this->_attrToGroup[$attr->getHtmlId()] = $group;
    }

    function addAttrFieldValue(Workset_Model_Value_Form_Interface $attr, $value, $overwrite = true) {
        if (isset($this->_attrElements[$attr->getHtmlId()])) {
            $element = & $this->_attrElements[$attr->getHtmlId()];

            if ($element['multiple']) {
                if (is_array($value) && $overwrite) {
                   $element['value'] = $value;
                } elseif (!$overwrite) {
                   $element['value'] = (array)$value + $element['value'];
                }

            } else {
                $element['value'] = $value;
            }
        }
    }

    function addAttrOptions($options, $groupId = null) {
        if ($options instanceof Zend_Config) {
            $options = $options->toArray();
        } elseif (!is_array($options)) {
            throw new Workset_Model_Exception('Options type must be an array or Zend_Config');
        }

        if (null === $groupId) {
            $groupId = self::ATTR_PREFIX;
        }

        if (isset($this->_attrOptions[$groupId])) {
            $this->_attrOptions[$groupId] = array_merge($this->_attrOptions[$groupId], $options);
        } else {
            $this->_attrOptions[$groupId] = $options;
        }
    }

    function addAttrFieldDecorator(Workset_Model_Value_Form_Interface $attr, $decorator, $order = null, $options = null) {
        $decorator = ucfirst($decorator);

		if (!isset($this->_attrDecoratorOrder[$attr->getHtmlId()])) {
            $type = $attr->getType();
            $isFile = $attr->typeOf(Workset_Model_Value_Form_Interface::T_FILE);

            if (isset(self::$_attrDefaultDecoratorOrder[$type])) {
                $this->_attrDecoratorOrder[$attr->getHtmlId()] = self::$_attrDefaultDecoratorOrder[$type];
            } elseif ($isFile) {
                $this->_attrDecoratorOrder[$attr->getHtmlId()] = self::$_attrDefaultDecoratorOrder[Workset_Model_Value_Form_Interface::T_FILE];
            } else {
                $this->_attrDecoratorOrder[$attr->getHtmlId()] = self::$_attrDefaultDecoratorOrder['default'];
            }
		}

		$decOrder = & $this->_attrDecoratorOrder[$attr->getHtmlId()];
		$updateOrder = 0;

		if (null === $order || $order < 0) {
            if (isset($decOrder[$decorator])) {
				$order = $decOrder[$decorator];
				$updateOrder = $order + 1;
			} else {
				$max = 0;
				foreach ($decOrder as $decor => $pos) {
					if ($pos > $max) {
						$max = $pos;
					}
				}
				$order = $max + 1;
			}
        }

		$decor = array(
			array($decorator.uniqid() => $decorator),
			$options
		);

		if (!isset($this->_attrDecorators[$attr->getHtmlId()])) {
            if (isset(self::$_attrDefaultDecoratorOrder[$type])) {
                $decors = self::$_attrDefaultDecorators[$type];
            } elseif ($isFile) {
                $decors = self::$_attrDefaultDecorators[Workset_Model_Value_Form_Interface::T_FILE];
            } else {
                $decors = self::$_attrDefaultDecorators['default'];
            }

			$decors[$order] = $decor;

			$this->_attrDecorators[$attr->getHtmlId()] = $decors;

		} elseif (!$updateOrder) {

            $this->_attrDecorators[$attr->getHtmlId()][$order] = $decor;

		} else {
			foreach ($decOrder as $key => $order) {
				if ($order > $updateOrder) {
					$decOrder[$key] += 1;
				}
			}

			$decors = & $this->_attrDecorators[$attr->getHtmlId()];

			$begin = array_slice($decors, 0, $updateOrder);
			$end = array_slice($decors, $updateOrder);

			$begin[$updateOrder] = $decor;

			$decors = array_merge($begin, $end);
		}
    }

    function addAttrFieldButton(Workset_Model_Value_Form_Interface $attr, $button, $options = null) {

		if (!is_array($options)) {
			$options = array(
				'type' => $button
			);
		} else {
            $options['type'] = $button;
        }

		$this->addAttrFieldDecorator($attr, 'Button', null, $options);
    }

    function addAttrFieldFileAttachment(Workset_Model_Value_Form_Interface $attr, $files, $options = null) {

        if (!is_array($options)) {
			$options = array(
				'files' => $files
			);
		} else {
            $options['files'] = $files;
        }

        $this->addAttrFieldDecorator($attr, 'Attachment', null, $options);

    }

    function addAttrFieldText(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null) {
        if (null !== $value && $attr->isMultiple()) {
            $value = (array)$value;
        } else {
            $value = (string)$value;
        }

        $name = $attr->getHtmlId();

        $this->addAttrElement($attr, 'text', $name, $value, $options);
    }

    function addAttrFieldCheckbox(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null) {
        $options = (array)$options;

        $options += array(
            'checked' => 0,
            'checkedValue' => 1,
            'uncheckedValue' => 0,
        );

        if (null !== $value && $attr->isMultiple()) {
            $value = (array)$value;
        } else {
            $value = (int)(bool)$value;
        }

        $name = $attr->getHtmlId();

        $this->addAttrElement($attr, 'checkbox', $name, $value, $options);
    }

    function addAttrFieldSelect(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null) {
        if ($attr->isMultiple()) {
            $type = 'multiselect';
            $value = (array)$value;
        } else {
            $type = 'select';
        }

        if ($attr->isEnum() && !isset($options['multiOptions'])) {
            $options['multiOptions'] = $attr->getEnumItems()->setKeyIndex('id')->toArray('value');
            $options['multiOptions'][0] = null;

            ksort($options['multiOptions']);
        }

        $name = $attr->getHtmlId();

        $this->addAttrElement($attr, $type, $name, $value, $options);
    }

    function addAttrFieldFile(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null) {

		$options += array(
			'validators' => array(
				//размер файла
				array(
					'validator' => 'Size',
					'breakChainOnFailure' => true,
					'options' => self::UPLOAD_FILE_SIZE.'Mb'
				),
				//число файлов
				array(
					'validator' => 'Count',
					'breakChainOnFailure' => true,
					'options' => self::UPLOAD_FILE_COUNT
				),
				//суммарный размер файлов (для пакетной загрузки)
				array(
					'validator' => 'FilesSize',
					'breakChainOnFailure' => true,
					'options' => (self::UPLOAD_FILE_SIZE * self::UPLOAD_FILE_COUNT) .'Mb'
				),
			),
			'isArray' => $attr->isMultiple(),
			'ignore' => true
		);

        if ($attr->isImage()) {
            array_push($options['validators'], array(
                'validator' => 'isImage',
                'breakChainOnFailure' => true,
                'options' => array(
                    'image/gif',
                    'image/jpeg',
                    'image/png',
                    'image/bmp'
                )
            ));
        }

        $name = $attr->getHtmlId();

        $this->addAttrElement($attr, 'file', $name, $value, $options);
    }

    function addAttrFieldTextarea(Workset_Model_Value_Form_Interface $attr, $value = null, $options = null) {
        if (null !== $value && $attr->isMultiple()) {
            $value = (array)$value;
        } else {
            $value = (string)$value;
        }

        $name = $attr->getHtmlId();

        $this->addAttrElement($attr, 'textarea', $name, $value, $options);
    }

    function getAttrFieldName(Workset_Model_Value_Form_Interface $attr, $value = null) {
        if ($attr->isMultiple()) {
            //$name = self::ATTR_PREFIX.'['.$attr->getId().']';
            $name = $attr->getHtmlId(self::ATTR_PREFIX);
        } else {
            $name = $attr->getHtmlId();
        }
        return $name;
    }

    function addAttrElement(Workset_Model_Value_Form_Interface $attr, $type, $name, $value = null, $options = null) {

        if (is_array($value) && empty($value)) {
            $value = null;
        }

        $config = array();

        if (!isset($options['order'])) {
            $config['order'] = $this->_attrElementOrder = (count($this->_attrElements) + 1) * 1000;

        } elseif ($this->_attrElementOrder == 0 || $this->_attrElementOrder < $options['order']) {
            $config['order'] = $this->_attrElementOrder = $options['order'];
        }

		$config = array_merge($options, $config);

        $multiple = false;

        if (!$attr->isSelect() && !$attr->isEnum()) {
            $multiple = $attr->isMultiple();
        }

        if ($multiple) {

            $this->_attrElements[] = array(
                'multiple' => true,
                'offset' => 10,
                'app_id' => $attr->getModelId(),
                'id' => $attr->getHtmlId(),
                'value_type' => $attr->getType(),
                'isFile' => $attr->typeOf(Workset_Model_Value_Form_Interface::T_FILE),
                'overwrite' => true,
                'type' => $type,
                'name' => $name,
                'value' => $value,
                'options' => $config
            );

        } else {

			$this->_attrElements[] = array(
                'multiple' => false,
                'app_id' => $attr->getModelId(),
				'id' => $attr->getHtmlId(),
				'value_type' => $attr->getType(),
                'isFile' => $attr->typeOf(Workset_Model_Value_Form_Interface::T_FILE),
                'overwrite' => true,
				'type' => $type,
				'name' => $name,
				'value' => $value,
				'options' => $config
			);
        }

    }

	function addToDisplayGroup($name, $element, $options = null) {
		if (!$element instanceof Zend_Form_Element) {
			$element = $this->getElement($element);
		}

		if ($element) {
			$displayGroup = $this->getDisplayGroup($name);
			if (!$displayGroup) {
				if (!is_array($options)) {
					$options = array(
						'decorators' => $this->_displayGroupDecorators
					);
				} elseif (!isset($options['decorators'])) {
					$options['decorators'] = $this->_displayGroupDecorators;
				}

				$options['order'] = $this->_attrDisplayGroupOrder++;
				$this->addDisplayGroup(array($element->getName()), $name, $options);
			} else {
				$displayGroup->addElement($element);
				unset($this->_order[$element->getName()]);
			}
		}
	}

    protected function _initAttrFields() {

        if ($this->_attrElements) {

			foreach ($this->_attrElements as $config) {

                $attrId = $config['name'];

                if (!$config['multiple']) {
                    $config['value'] = array($config['value']);
                } elseif ($config['value'] === null) {
                    $config['value'] = array(null);
                } else {
                    $config['value'] = (array)$config['value'];
                    //ksort($config['value']); Х.з зачем он нужен
                    unset($this->_attrElements[$attrId]);
                }

				$belongsTo = $config['options']['belongsTo'];

                //$belongsTo != self::ATTR_PREFIX &&
				if (0 < ($pos = strpos($belongsTo, '['))) {
					$basePrefix = substr($belongsTo, 0, $pos);
				} else {
					$basePrefix = $belongsTo;
				}

				$this->setAttrPrefix($basePrefix);

                $first = true;

                foreach ($config['value'] as $key => $value) {
                    $name = $config['name'];
					$configName = null;
					$options = $config['options'];

					if (false !== strpos($name, '[')) {

						$configName = $name;

						$parts = array();

						while ($pos = strpos($name, '[')) {
							$parts[] = trim(substr($name, 0, $pos), ']');

							$name = trim(substr($name, $pos + 1), ']');
						}

						if ($parts) {
							if (!isset($options['belongsTo'])) {
								$options['belongsTo'] = '';
							}

							foreach ($parts as $part) {
								$options['belongsTo'] .= "[$part]";
							}
						}
					}

                    if (isset($this->_elements[$name])) {
                        if (!empty($config['app_id'])) {
                            $name .= '_'.$config['app_id'];
                        } else {
                            $name .= '_'.uniqid();
                        }
                    }

					if ($configName) {
						$this->_attrElements[$configName] = $config;

					} elseif ($config['multiple']) {
                        if (isInt($key)) {
                            $name = $name.'_'.$key;
                        } else {
                            $name = $key;
                        }
                        $this->_attrElements[$name] = $config;
                    }

                    if (!isset($config['options']['decorators'])) {
                        if (isset($this->_attrDecorators[$config['id']])) {
                            $decors = $this->_attrDecorators[$config['id']];

                        } elseif (isset(self::$_attrDefaultDecorators[$config['value_type']])) {
                            $decors = self::$_attrDefaultDecorators[$config['value_type']];

                        } elseif (!empty($config['isFile'])) {
                            $decors = self::$_attrDefaultDecorators[Workset_Model_Value_Type_Interface::T_FILE];

                        } else {
                            $decors = self::$_attrDefaultDecorators['default'];
                        }

                        foreach ($decors as $k => $decor) {
                            if (is_string($decor)) {
                                unset($decors[$k]);
                                continue;
                            }

                            if ($config['multiple']) {
                                if (isset($decor['decorator'])) {
                                    $decors[$k]['options']['place_id'] = $key;
                                } elseif (count($decor) > 1) {
                                    $decors[$k][1]['place_id'] = $key;
                                } else {
                                    $decors[$k][1] = array('place_id' => $key);
                                }

                            }
                        }

                        $options['decorators'] = $decors;
                    }

                    if (!$first) {
                        $options['label'] = '';
                    } else {
                        $first = false;
                    }

					//@todo если файл уже сохранен ранее или множественное поле выбора файла,
					//то сбросим флаг required
					if (!empty($options['required']) && $config['isFile']) {
						if ( (!$config['multiple'] && null !== $value) || $config['multiple']) {
							$options['required'] = false;
						}
					}

                    $this->addElement($config['type'], $name, $options);

                    $element = $this->getElement($name);

					if ($config['isFile']) {
						$element->setValueDisabled(true);
						$element->addPrefixPath('Workset_File', 'Workset/File', Zend_Form_Element_File::TRANSFER_ADAPTER);

						/*if (null !== $value) {
							$this->addElement('hidden', 'stored_files['. $name .']', array(
								'disableLoadDefaultDecorators' => true,
								'decorators' => self::$_attrDefaultDecorators['hidden']
							));
						}*/

					} elseif (null !== $value) {
                        $element->setValue($value);
                    }

                    if (isset($this->_attrToGroup[$config['id']])) {
                        $group = $this->_attrToGroup[$config['id']];
                        $this->addToDisplayGroup($group, $element, $this->_attrGroups[$group]);
                    }

                    if (isset($config['offset'])) {
                        $config['options']['order'] += $config['offset'];
                    }

                    $group = $attrId;
                }
            }
		}
    }

	function render(Zend_View_Interface $view = null) {
        $this->init();

		return parent::render($view);
	}

    function getValues($suppressArrayNotation = false) {
        $this->init();

        if (!$this->_attrElements) {
            return parent::getValues($suppressArrayNotation);
        }

        $values = parent::getValues($suppressArrayNotation);

		if ($this->_namedPrefixs) {

			//сейчас идет разбор только массива атрибутов
			//$prefixes = array_keys($this->_namedPrefixs);
			//$prefixes = array(self::ATTR_PREFIX);

			foreach ($this->_namedPrefixs as $prefix) {

				if (!isset($values[$prefix])) {
					continue;
				}

                $parseRealId = !( isset($this->_attrOptions[$prefix]) && false == $this->_attrOptions[$prefix]['parseRealId'] );

				foreach ((array) $values[$prefix] as $key => $value) {

					$updateValue = false;

					if (is_array($value)) {

						foreach ($value as $valueKey => $valueItem) {

							if (null === $valueItem) {
								unset($value[$valueKey]);
								continue;
							}

							$newValueKey = $this->getValueIdNotation($valueKey);

							if ($valueKey != $newValueKey) {
								unset($value[$valueKey]);
								$value[$newValueKey] = $valueItem;
							}

						}

						$updateValue = true;

					}

                    if ($parseRealId) {
                        $newKey = $this->getFieldId($key);
                    } else {
                        $newKey = $key;
                    }

					if ($key != $newKey) {
                        unset($values[$prefix][$key]);
                        $updateValue = true;
                    }

					if ($updateValue) {
						$values[$prefix][$newKey] = $value;
					}

				}

			}
		}

        return $values;
    }

    function getValueIdNotation($key) {
        if (!isInt($key)) {
            $key = preg_replace("/^[a-zA-Z0-9]+[\-\_]/", "", $key);
        }
        return $key;
    }

	function getObjectIdNotation($data) {
		if (!is_array($data)) {
			return stripNotDigit($data);
		}
	}

    function getFieldId($key) {
        if (isInt($key)) {
            return $key;
        } else {
            $key = stripNotDigit($key);
        }
		return $key;
    }

    function setAttrPrefix($prefix) {
        if (!in_array($prefix, $this->_namedPrefixs)) {
            $this->_namedPrefixs[] = (string)$prefix;
        }
        return $this;
    }

    function isValid($values) {

        foreach (self::$_editModes as $mode => $options) {

            if (isset($values[$mode])) {
                $this->_editMode = $mode;
                break;
            }

        }

        if ($this->_namedPrefixs) {

            foreach ($this->_namedPrefixs as $prefix) {

                if (!isset($values[$prefix])) {
                    continue;
                }

                foreach ($values[$prefix] as $key => $value) {

                    if (is_array($value) && count($value) > 1) {

                        $element = null;

						foreach ($this->_attrElements as $name => $item) {
							if ($item['name'] == $key) {
								if ($item['multiple']) {
									$element = & $this->_attrElements[$name];
								}
								break;
							}
						}

                        if ($element) {

                            if ($element['overwrite']) {
                                $element['value'] = array();
                            }

                            foreach ($value as $itemKey => $itemValue) {
                                if (!emptyNotZero($itemValue)) {
                                    $element['value'][$itemKey] = $itemValue;
                                    unset($value[$itemKey]);
                                }
                            }
                        }

                        unset($element);
                    }
                }
            }
        }

		$this->init();

        return parent::isValid($values);

    }

    function init() {

        if (false == $this->_initForm) {

			$this->addElementPrefixPath('Catalogue_Form', MODULES_PATH . '/catalogue/forms');
			
            $this->setMethod('POST');

            $this->setAttrib('id', uniqid('form'));

            $this->setAttrib('class', 'zend_form');

            $this->setDisableLoadDefaultDecorators(true);

            $this->setDecorators(array(
                array(
                    'decorator' => 'FormElements',
                ),
                array(
                    'decorator' => 'Form',
                )
            ));

            $this->setDisplayGroupDecorators(array(
                array('decorator' => 'FormElements'),
                array(
                    'decorator' => 'HtmlTag',
                    'options' => array(
                        'tag' => 'dl'
                    )
                ),
                array('decorator' => 'Fieldset'),
            ));

            $this->_initForm = true;

			$this->addAttrOptions(array('parseRealId' => true), self::ATTR_PREFIX);

        }

        if (false == $this->_initAttrFields && $this->_attrElements) {

            $this->_initAttrFields();

            $this->_initAttrFields = true;
        }

    }

}

?>